#ifndef CAMERA_H_
#define CAMERA_H_

#include "Vec3.h"
#include "EventHandler.h"
class Scene;

class Camera : public EventHandler
{
public:
    /* Construction and Destruction */
    Camera();
    virtual ~Camera(){}

    /* Set functions */
    void SetPosition(const Vec3& pos);
    void SetLook(const Vec3& pos);
    void SetUp(const Vec3& pos);

    void SetPosition(float x, float y, float z);
    void SetLook(float x, float y, float z);
    void SetUp(float x, float y, float z);
    
    void SetNearFar(float near, float far)
    {
        m_near = near;
        m_far = far;
    }
    float GetFar(){return m_far;}
    /* To be called after all set functions are in place */
    void ComputeONB(); //Orthonormal Basis

    /* Calculate the direction of the ray for pixel position x,y and stores it in target */
    virtual void ComputeDirection(int x, int y, Vec3* target, Scene* s);

    const Vec3& GetPos();

    virtual void OnKeyBoardDownEvent(const SDL_KeyboardEvent&);
    float GetNear()
    {
        return m_near;
    }
public:
    /* The cameras position */
    Vec3 m_pos;
    /* The cameras look vector (can  be a point in space, or a normalized direction) */
    Vec3 m_look;
    /* Pretty much always 0,1,0 */
    Vec3 m_up;
    /* This is the opposite direction to the look vector aka the view direction */
    Vec3 m_w;    
    /* This is perpendicular to m_w and the UP vector(0,1,0) */
    Vec3 m_u;
    /* This is perpendicular to both u and w */
    Vec3 m_v;

/*  (m_v) (m_up) (m_look)
        \   |   /
         \  |  /
          \ | /
           \|/__________(m_u)
           /(pos) 
          /
         /
        /
    (m_w)
*/

    /* the distance from the cameras position to the lens (near plane )*/
    float m_near;
    float m_far;

};


#endif